package main

import (
	"container/list"
	"fmt"
)

// Define SD type
type ServiceDiscoveryItem struct {
	Hostname string
	Port     int
}

// Define error
type ServiceDiscoveryError struct {
	error_info string
}

func (err ServiceDiscoveryError) Error() string {
	return err.error_info
}

func (item ServiceDiscoveryItem) String() string {
	return fmt.Sprintf("hostname: %s. port: %d", item.Hostname, item.Port)
}

// storage all item
var itemMap map[string]*list.List = make(map[string]*list.List)

func AddService(name string, hostname string, port int) {
	// initial item of Service
	item := ServiceDiscoveryItem{hostname, port}

	// Check is exists.
	aList, ok := itemMap[name]
	if !ok {
		aList = list.New()
	}

	fmt.Println("[AddService] ", item.String())

	aList.PushBack(item)
}

func RemoveService(name string, hostname string, port int) {
	// Check is exists
	if aList, ok := itemMap[name]; ok {
		// For each list and find match item
		for v := aList.Front(); v != nil; v = v.Next() {
			item := v.Value.(ServiceDiscoveryItem)
			// Match Hostname
			if item.Hostname == hostname {
				// Match Port
				if item.Port == port {
					aList.Remove(v)
				}
			}
		}

		// Check List is empty, and delete of id
		if aList.Len() == 0 {
			delete(itemMap, name)
		}
	}
}

func GetService(name string) (ServiceDiscoveryItem, error) {
	// Check is exists
	if aList, ok := itemMap[name]; ok {
		return aList.Front().Value.(ServiceDiscoveryItem), nil
	}

	return ServiceDiscoveryItem{"", 0}, ServiceDiscoveryError{"Not found Service."}
}
